package com.gis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gis.entity.SedimentData;
import com.gis.entity.StationData;
import com.gis.entity.WaterQualityData;
import com.gis.exception.CustomException;
import com.gis.service.StationDataService;
import com.gis.utils.PythonUtil;
import jakarta.servlet.ServletOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gis.entity.EcologyData;
import com.gis.mapper.EcologyDataMapper;
import com.gis.service.EcologyDataService;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static org.apache.commons.lang.StringUtils.capitalize;

@Slf4j
@Service
public class EcologyDataServiceImpl extends ServiceImpl<EcologyDataMapper, EcologyData> implements EcologyDataService{
    @Autowired
    private StationDataService stationDataService;
    @Autowired
    private PythonUtil pythonUtil;
    @Value("${python.path}")
    private String pythonPath;
    @Autowired
    private EcologyDataMapper ecologyDataMapper;
    @Override
    public void generateTIF(ServletOutputStream outputStream, String param, int year, String season) {
        List<EcologyData> ecologyDataList = getAllByYearAndSeason(year, season);
        List<List<Float>> tripleList = new ArrayList<>();
        for(EcologyData ecologyData : ecologyDataList){
            String methodName = "get" + capitalize(param);
            Method method = null;
            try {
                method = EcologyData.class.getMethod(methodName);
                Float paramValue = (Float) method.invoke(ecologyData);
                if(paramValue != null){
                    StationData stationData = stationDataService.getById(ecologyData.getStationId());
                    List<Float> data= new ArrayList<>();
                    data.add(stationData.getLongitude());
                    data.add(stationData.getLatitude());
                    data.add(paramValue);
                    tripleList.add(data);
                }
            } catch (NoSuchMethodException e) {
                throw new CustomException("方法不存在");
            } catch (InvocationTargetException e) {
                throw new CustomException("反射异常");
            } catch (IllegalAccessException e) {
                throw new CustomException("反射异常");
            }
        }
        if(tripleList.isEmpty()){
            log.info("无数据进行空间分析");
            throw new CustomException("无数据进行空间分析");
        }
        boolean success = pythonUtil.runSpatialAnalysis(tripleList);
        if(success){
            String tifPath = pythonPath + "/tif/output.tif";
            File file = new File(tifPath);
            try (FileInputStream fis = new FileInputStream(file);
                 BufferedInputStream bis = new BufferedInputStream(fis)) {
                byte[] bytes = new byte[(int) file.length()];
                int bytesRead = bis.read(bytes);
                if (bytesRead != -1) {
                    outputStream.write(bytes, 0, bytesRead);
                }
            } catch (IOException e) {
                throw new CustomException("tif文件读取或写入失败"+e);
            }
        }else {
            throw new CustomException("空间分析失败");
        }
    }

    @Override
    public List<EcologyData> getAllByYearAndSeason(int year, String season) {
        QueryWrapper<EcologyData> wrapper = new QueryWrapper<EcologyData>()
                .eq("year", year)
                .eq("season", season);
        return list(wrapper);
    }

    /**
     * 获取某时间段内数据
     * @param stationId
     * @param fromYear
     * @param fromSeason
     * @param toYear
     * @param toSeason
     * @return
     */
    @Override
    public List<EcologyData> getFromYearAndSeason(int stationId, int fromYear, String fromSeason, int toYear, String toSeason) {
        List<EcologyData> ecologyDataList = ecologyDataMapper.getFromYear(stationId, fromYear, toYear);
        List<EcologyData> result = new ArrayList<>();
        for (EcologyData ecologyData : ecologyDataList){
            if(ecologyData.getYear()==fromYear){
                if(fromSeason.equals("fall")&&ecologyData.getSeason().equals("spring")){
                    continue;
                }
            }
            if(ecologyData.getYear()==toYear){
                if(toSeason.equals("spring")&&ecologyData.getSeason().equals("fall")){
                    continue;
                }
            }
            result.add(ecologyData);
        }
        return result;
    }
}
